/**
 * Copyright 2011 Honeywell Federal Manufacturing & Technologies, LLC. This material was produced under U.S. Government
 * contract DE-ACO4-01AL66850, Honeywell Federal Manufacturing & Technologies, LLC, (FM&T) with the U. S. Department of
 * Energy for the operation of the Kansas City Plant . The U.S. Government has rights to use, reproduce, and distribute
 * this software.  NEITHER THE GOVERNMENT NOR Honeywell Federal Manufacturing & Technologies, LLC, MAKES ANY WARRANTY,
 * EXPRESS OR IMPLIED, OR ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE.  If software is modified to produce
 * derivative works, such modified software should be clearly marked, so as not to confuse it with the version available
 * from FM&T.
 *
 * Additionally, this program is free software; you can redistribute it and/or modify it under the terms of the GNU
 * General Public License Version 3 published by the Free Software Foundation. Accordingly, this program is distributed in
 * the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with this library.
 * If not, see http://www.gnu.org/licenses/.
 */
/**
 * NOTICE:  This computer software was prepared by Honeywell Federal Manufacturing &
 * Technologies, hereinafter the Contractor, under Contract NO. DE-AC04-01AL66850 with 
 * the U.S. Department of Energy (DOE).  All rights in the computer software are 
 * reserved by DOE on behalf of the United States Government and the Contractor as 
 * provided in the Contract.  You are authorized to use this program for Government 
 * purposes but it is not to be released or distributed to the public.  Neither the 
 * Government nor the Contractor makes any warranty, express or implied, or assumes 
 * any liability for the use of this software.  This notice including this sentence 
 * must appear on any copies of this computer software.
 */

package org.braintrain.tapestry.view;

import com.javaforge.tapestry.spring.annotations.InjectSpring;
import com.kcp.ko.authentication.domain.AuthenticatableRoleUser;
import com.kcp.ko.authentication.service.UserService;
import com.kcp.ko.fmtnmlib.service.HibernatePersistenceService;
import org.apache.tapestry.PageRedirectException;
import org.apache.tapestry.annotations.InjectObject;
import org.apache.tapestry.annotations.InjectPage;
import org.apache.tapestry.annotations.InjectState;
import org.apache.tapestry.event.PageAttachListener;
import org.apache.tapestry.event.PageEndRenderListener;
import org.apache.tapestry.event.PageEvent;
import org.apache.tapestry.event.PageValidateListener;
import org.apache.tapestry.html.BasePage;
import org.apache.tapestry.services.ServiceMap;
import org.braintrain.domain.User;
import org.braintrain.domain.types.BrainTrainRole;
import org.braintrain.services.ContentService;
import org.braintrain.services.NavigationService;
import org.braintrain.services.search.users.UniqueUserQueryFactory;
import org.braintrain.tapestry.aso.EditingASO;
import org.braintrain.tapestry.aso.Visit;
import org.braintrain.tapestry.view.util.SessionPagePropertyPersistenceStrategy;

import javax.servlet.http.HttpServletRequest;

/**
 * The Secured Base Page for BrainTrain.  Handles the basic application user authorization.
 * Also, page persistence is implemented here
 * 
 * @author John Ericksen
 *
 */

public abstract class BrainTrainSecuredBasePage extends BasePage implements PageValidateListener, PageAttachListener{

    @InjectState("visit")
    public abstract Visit getBraintrainVisit();
    
    @InjectPage("NotAuthorized")
    public abstract BasePage getNotAuthorizedPage();

    @InjectObject("service:tapestry.globals.HttpServletRequest")
    public abstract HttpServletRequest getHttpServletRequest();

    @InjectObject("service:tapestry.services.ServiceMap")
    public abstract ServiceMap getServiceMap();

    @InjectSpring("contentService")
    public abstract ContentService getContentService();
    
    @InjectSpring("genericHibernateService")
    public abstract HibernatePersistenceService getGenericService();
    
    @InjectSpring("userService")
    public abstract UserService getUserService();

    @InjectSpring("navigationService")
    public abstract NavigationService getNavigationService();

    @InjectState("editingaso")
    public abstract EditingASO getEditingASO();

    public boolean isUserAccessGranted()
    {
        return getBraintrainVisit().getAuthenticatedUser().hasBasicAccess();
    }
    
    /**
     * Validate the user
     * 
     */
    public void pageValidate(PageEvent event) {
        if(!event.getRequestCycle().isRewinding())
        {
        	AuthenticatableRoleUser authenticatedUser = getUserService().getUser(getHttpServletRequest());
        		
            if(authenticatedUser != null)
            {
                User user = getGenericService().findUnique(new UniqueUserQueryFactory(authenticatedUser.getProfile().getId()));
                if(user != null && !user.isDisabled())
                {
                    getBraintrainVisit().setAuthenticatedUser(authenticatedUser);
                    getBraintrainVisit().setUser(user);
                }
                if(user == null || !isUserAccessGranted())
                {
                    throw new PageRedirectException("NotAuthorized");
                }
            }
            else
            {
                throw new PageRedirectException("NotAuthorized");
            }
        }
        
    }
    
    /**
     * Convenience method for user roles
     * @return
     */
    
    public boolean isCmStaff()
    {
        return BrainTrainRole.cmstaff.checkRole(getBraintrainVisit().getAuthenticatedUser());
    }
    
    public boolean isAdmin()
    {
        return BrainTrainRole.admin.checkRole(getBraintrainVisit().getAuthenticatedUser());
    }
    
    public boolean isContentCreator()
    {
        return BrainTrainRole.contentcreator.checkRole(getBraintrainVisit().getAuthenticatedUser());
    }
    
    public boolean isDeltaUser()
    {
        return BrainTrainRole.checkRoles(getBraintrainVisit().getAuthenticatedUser(),
                new BrainTrainRole[] {BrainTrainRole.contentcreator, BrainTrainRole.cmstaff});
    }
    
    /**
     * Page Persistence method.
     * 
     * @param event
     */
    public void pageAttached(PageEvent event) {
    	addPageEndRenderListener(new SessionPagePropertyRenderListener());
    }

    private static class SessionPagePropertyRenderListener implements PageEndRenderListener{
        /**
         * After rendering, store the page name in the session so the "session:page" persistence strategy can use it.
         * @see org.apache.tapestry.event.PageEndRenderListener#pageEndRender(org.apache.tapestry.event.PageEvent)
         */
        public void pageEndRender(PageEvent e) {
                final String pageKey = SessionPagePropertyPersistenceStrategy
                         .getLastPageKey(e.getRequestCycle().getInfrastructure().getApplicationId());
                e.getRequestCycle()
                 .getInfrastructure()
                 .getRequest()
                 .getSession(true)
                 .setAttribute(pageKey, e.getPage().getPageName());
        }
    }
}
